package com.fare.taluo.application.impl.analyse;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hbase.client.Result;
import org.foreveross.hbase.client.HBaseHelper;
import org.foreveross.hbase.client.HBasePlaneinfoHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fare.taluo.application.FreightPriceApplication;
import com.fare.taluo.application.analyse.AirCompanyTrendContrastFlightApplication;
import com.fare.taluo.application.fetl.SinglePlaneInfoApplication;
import com.fare.taluo.core.domain.config.channel.SourceEntity;
import com.fare.taluo.core.domain.config.city.PortEntity;
import com.fare.taluo.core.domain.config.line.FlightInfoEntity;
import com.fare.taluo.fetl.domain.entity.SinglePlaneInfoEntity;
import com.fare.taluo.fusionCharts.FusionChartsTemplateModel;
import com.fare.taluo.fusionCharts.SimpleFusionChartsBuilder;
import com.fare.taluo.util.FusionChartsUtil_2;
import com.fare.taluo.util.I18nUtil;
import com.fare.taluo.util.flightInfo.FlightInfoSortUtil;
import com.fare.taluo.util.flightInfo.SameChannelContrastUtil;
import com.fare.taluo.vo.core.HBaseFilterVO;
import com.fare.taluo.vo.core.PlaneInfo;
import com.fare.taluo.vo.report.SameChannelContrastVO;
import com.fare.taluo.vo.report.SpreadVo;
import com.fare.taluo.vo.report.XmlVO;

/**
 * 航班走势对比实现累
 * 
 * @author Administrator 选择多个航班进行比较，数据来源于【官网】或者【各大渠道】 当数据来源为【官网】时，则渠道为航班对应的【官网】
 *         用户选择官网，则dataSourceHbaseKey为空 生成的price 和set 会经过报表工具FusionChartsUtil_2
 *         的一系列处理。
 * 
 * 
 *         PS 20130812 有一种比较特殊的情况，比如今天早上抓到的某个航班是15：00起飞，但是下午抓到的缺失16：00起飞
 *         oracle数据库只会保存一条记录。所以更新了最新的16：00，导致之前的15：00抓到的数据从这个16：00起飞的记录查不出来！！！
 *         所以现在的策略是，数据库会保存【多条记录】，每个都有不同的起飞时间，我们业务逻辑里全部取出来，进行筛选最低价的航班。
 *         我们会以List<List<FlightInfo>> 代表选择的每个航班的在oracle对应的多个记录，有多个记录表示有出现不同的起飞时间
 * 
 * @author guokenye
 * 
 */
@Service("airCompanyTrendContrastFlightApplicationImpl")
public class AirCompanyTrendContrastFlightApplicationImpl implements
		AirCompanyTrendContrastFlightApplication {
	@Resource(name = "singlePlaneInfoApplication")
	private SinglePlaneInfoApplication singlePlaneInfoApplication;
	private final static String Table = "LP_FLIGHT";// 所查的表

	// 渠道_起点(使用三字码)_终点(使用三字码)_航班号_航班日期(年月日时) 00001CANNKG00ZH96772013021307

	// private FreightPriceApplication freightPriceApplication;
	//
	//
	// public FreightPriceApplication getFreightPriceApplication() {
	// return freightPriceApplication;
	// }
	//
	//
	// public void setFreightPriceApplication(
	// FreightPriceApplication freightPriceApplication) {
	// this.freightPriceApplication = freightPriceApplication;
	// }

	@Override
	public String getFusionChartsXMLStr(String fromCityCode, String toCityCode,
			String flightStartDate, String flightEndDate, Integer futureDay,
			String[] compareFlights, String dataSourceHbaseKey, String priceType,Locale locale)
			throws Exception {
		PortEntity pe = new PortEntity();
		PortEntity fromPort = pe.findByPortCode(fromCityCode);// 出发城市实体
		PortEntity toPort = pe.findByPortCode(toCityCode);// 到达城市实体
		List<String> flightDate = new ArrayList<String>();// 航班日期list
			flightDate = FusionChartsUtil_2.getDatesStr(flightStartDate,
					flightEndDate);
		Map<String, PlaneInfo> map = new HashMap<String, PlaneInfo>();
		FlightInfoEntity fe = new FlightInfoEntity();

		// 选择的每个航班的在oracle对应的多个记录，有多个记录表示有出现不同的起飞时间
		List<List<FlightInfoEntity>> fss = new ArrayList<List<FlightInfoEntity>>();
		for (String f : compareFlights) {
			List<FlightInfoEntity> fs = fe.findByFlightNo(f.trim());// 找到航班号对应的在数据库的里多条记录
			fss.add(fs);
		}
		// 渠道_起点(使用三字码)_终点(使用三字码)_航班号_航班日期(年月日时) 00001CANNKG00ZH96772013021307
		// 20000PEKSZX00CZ32562013073108
		FusionChartsTemplateModel model = FusionChartsTemplateModel
				.getNewDefaultInstance();// 报表模型
		model.addChartAttr(FusionChartsTemplateModel.AN_Caption,
				fromPort.getCityName() + "-" + toPort.getCityName()
						+ (null==I18nUtil.getProperties(locale).get("xmlutil.flightsTrend")? " 航空公司航班走势对比":I18nUtil.getProperties(locale).get("xmlutil.flightsTrend")));
		//TODO 国际化
		model.addCategroyLabels(FusionChartsUtil_2
				.getDatesStrFormatMMdd(flightDate));
		long dataSetId = 1000L;
		SourceEntity source = new SourceEntity();
		for (List<FlightInfoEntity> fs : fss) {// 每个航班号，可能的多条记录
			if (fs != null && !fs.isEmpty()) {
				List<PlaneInfo> infos = new ArrayList<PlaneInfo>();
				String channelKey = null;
				if (dataSourceHbaseKey == null
						|| "".equals(dataSourceHbaseKey.trim())) {// 数据来源为官网，需要逐一匹对
					PlaneInfo temp = null;
					for (FlightInfoEntity planeInfo : fs) {
						if(planeInfo.getFlightNo().contains(planeInfo.getCompanyCode())){
							SourceEntity company = source.findByCarrierKey(
									planeInfo.getCompanyCode()).get(0);
							channelKey = company.getHbaseKey();
						}
						
					}
					
					
					
				} else {// 数据来源为渠道
					channelKey = dataSourceHbaseKey;
				}
				List<SinglePlaneInfoEntity> tempEntityList = singlePlaneInfoApplication.findPlaneInfo(channelKey,null, fromCityCode, toCityCode, null, fs.get(0).getFlightNo());
				//过滤航班日期
				tempEntityList = SameChannelContrastUtil.filterByDate(tempEntityList,flightDate);
				if ("lowest".equalsIgnoreCase(priceType)) {
					tempEntityList = SameChannelContrastUtil.getLowestByLineEachDay(tempEntityList, flightDate);
				} else if ("highest".equalsIgnoreCase(priceType)) {
					//否则找到最高价
					tempEntityList = SameChannelContrastUtil.getHighestByLineEachDay(tempEntityList, flightDate);
				}
				if(com.fare.taluo.util.StringUtils.checkList(tempEntityList)){
					infos.addAll(SameChannelContrastUtil.getPlaneInfoList(tempEntityList));
				}
				// 查找最低价类型
				if ("lowest".equalsIgnoreCase(priceType)) {
					infos = FlightInfoSortUtil
							.generatePlaneInfosInTodayCrawlOrderByFlightBatch(
									infos, flightDate);
				} else if ("highest".equalsIgnoreCase(priceType)) {
					// 查找最高价类型
					infos = FlightInfoSortUtil
							.generatePlaneInfosInTodayCrawlOrderByFlightBatchHighestPrice(
									infos, flightDate);
				}

				// 找出单个渠道价差表格
				map = SameChannelContrastUtil.getSingleSpreadForm(flightDate,
						infos, map);

				List<String> prices = // 开始提取数值
				FusionChartsUtil_2.getPriceValueByPlaneInfosAndFormat(infos,locale);
				String setsStr = FusionChartsUtil_2
						.generateDashedByFormat(prices,locale);// 完整的Set字符串
				// 构建模型
				model.createDataSet(dataSetId);
				model.addDataSetAttr(dataSetId,
						FusionChartsTemplateModel.AN_Seriesname, fs.get(0)
								.getFlightNo());
				model.addSetFullStrIntoDataSet(dataSetId, setsStr);
				model.addDataSetAttr(dataSetId,
						FusionChartsTemplateModel.AN_RenderAs, "Line");// 以折现展示数据
				dataSetId++;
			}

		}

		model.addStyleToObject("ToolTip",
				FusionChartsTemplateModel.STYLE_ToolTip_FontSize_15);// 全局style
		model.addStyleToObject("Caption",
				FusionChartsTemplateModel.STYLE_Caption_FontSize_15);// 全局style,标题15
		String xml = SimpleFusionChartsBuilder.getInstance().buildXMLStr(model);
		// 获得价差表格list
		List<SameChannelContrastVO> spreadVos = getSpreadListForm(flightDate,
				map, compareFlights);
		// SameChannelContrastVO s = new SameChannelContrastVO();
		// s.setNativeCarrier(xml);
		XmlVO xmlvo = new XmlVO();
		xmlvo.setXmlString(xml);
		StringBuffer resultBuffer = new StringBuffer();
		String jsonStr = com.fare.taluo.util.JsonUtil.toJson(spreadVos);
		resultBuffer.append("{\"Total\":" + spreadVos.size() + ","
				+ "\"Rows\":" + jsonStr + "," + "\"Xml\":"
				+ com.fare.taluo.util.JsonUtil.toJson(xmlvo) + "}");
		String json = resultBuffer.toString();
		// JsonUtil.toJSONOut(json);

		// return xml;
		return json;
	}

	private List<SameChannelContrastVO> getSpreadListForm(
			List<String> flightDate, Map<String, PlaneInfo> map,
			String[] flightNos) throws Exception {
		SourceEntity source = new SourceEntity();
		List<SameChannelContrastVO> vos = new ArrayList<SameChannelContrastVO>();
		for (String date : flightDate) {
			int i = 0;
			SameChannelContrastVO vo = new SameChannelContrastVO();
			for (String flightNoTemp : flightNos) {
				String flightNo = flightNoTemp.trim();
				// 设置本航
				if (i == 0) {
					PlaneInfo p = map.get(flightNo.substring(0, 2) + "_" + date) == null ? null
							: map.get(flightNo.substring(0, 2) + "_" + date);
					if (null != p) {
						vo.setNativeCarrier(p.getCarrierName());
						vo.setDate(date);
						vo.setNativePrice(p.getLowerPrice());
					} else {
					
						vo.setDate(date);
						vo.setNativeCarrier(source.findCompanyByCarrierKey(flightNo.substring(0, 2)).getShortName());
						vo.setNativePrice(null);
					}

				} else {
					// 获得非本航的其它航
					PlaneInfo p = map.get(flightNo.substring(0, 2) + "_" + date) == null ? null
							: map.get(flightNo.substring(0, 2) + "_" + date);
					SpreadVo svo = new SpreadVo();
					if (null != p) {
						svo.setCarrierName(p.getCarrierName());
						if (vo.getNativePrice() == null) {
							svo.setSpread(null);
							svo.setSpreadAmount(null);
						} else {
							svo.setSpreadAmount(""
									+ (Double.parseDouble(p.getLowerPrice()) - Double
											.parseDouble(vo.getNativePrice())));
							svo.setSpread(
SameChannelContrastUtil.getSpreadToString(p.getLowerPrice(),vo.getNativePrice()));
							
						}
						svo.setPrice(p.getLowerPrice());
					} else {
						
						svo.setCarrierName(source.findCompanyByCarrierKey(flightNo.substring(0, 2)).getShortName());
						svo.setSpread(null);
						svo.setSpreadAmount(null);
						svo.setPrice(null);
					}
					vo.getContrastList().add(svo);
				}
				i++;
			}
			vos.add(vo);
		}
		return vos;
	}
}
